package service

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

type ConfigService struct {
	configPath string
	logger     *logrus.Logger
	mutex      sync.RWMutex
	config     map[string]interface{}
}

func NewConfigService(configPath string, logger *logrus.Logger) *ConfigService {
	cs := &ConfigService{
		configPath: configPath,
		logger:     logger,
		config:     make(map[string]interface{}),
	}
	
	// 加载配置
	if err := cs.LoadConfig(); err != nil {
		logger.Warnf("Failed to load config: %v", err)
		cs.setDefaultConfig()
	}
	
	return cs
}

// LoadConfig 加载配置文件
func (cs *ConfigService) LoadConfig() error {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	
	// 检查配置文件是否存在
	if _, err := os.Stat(cs.configPath); os.IsNotExist(err) {
		cs.logger.Info("Config file not found, creating default config")
		return cs.createDefaultConfig()
	}
	
	// 读取配置文件
	data, err := ioutil.ReadFile(cs.configPath)
	if err != nil {
		return fmt.Errorf("failed to read config file: %v", err)
	}
	
	// 解析JSON配置
	if err := json.Unmarshal(data, &cs.config); err != nil {
		return fmt.Errorf("failed to parse config file: %v", err)
	}
	
	cs.logger.Info("Configuration loaded successfully")
	return nil
}

// SaveConfig 保存配置到文件
func (cs *ConfigService) SaveConfig() error {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	
	return cs.saveConfigInternal()
}

// saveConfigInternal 内部保存方法，不加锁
func (cs *ConfigService) saveConfigInternal() error {
	// 确保配置目录存在
	configDir := filepath.Dir(cs.configPath)
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return fmt.Errorf("failed to create config directory: %v", err)
	}
	
	// 序列化配置
	data, err := json.MarshalIndent(cs.config, "", "  ")
	if err != nil {
		return fmt.Errorf("failed to marshal config: %v", err)
	}
	
	// 写入文件
	if err := ioutil.WriteFile(cs.configPath, data, 0644); err != nil {
		return fmt.Errorf("failed to write config file: %v", err)
	}
	
	cs.logger.Info("Configuration saved successfully")
	return nil
}

// GetConfig 获取配置值
func (cs *ConfigService) GetConfig(key string) interface{} {
	cs.mutex.RLock()
	defer cs.mutex.RUnlock()
	
	return cs.getNestedValue(cs.config, key)
}

// SetConfig 设置配置值
func (cs *ConfigService) SetConfig(key string, value interface{}) error {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	
	cs.setNestedValue(cs.config, key, value)
	return cs.SaveConfig()
}

// GetAllConfig 获取所有配置
func (cs *ConfigService) GetAllConfig() map[string]interface{} {
	cs.mutex.RLock()
	defer cs.mutex.RUnlock()
	
	// 深拷贝配置
	result := make(map[string]interface{})
	cs.deepCopy(cs.config, result)
	return result
}

// UpdateConfig 批量更新配置
func (cs *ConfigService) UpdateConfig(updates map[string]interface{}) error {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	
	for key, value := range updates {
		cs.setNestedValue(cs.config, key, value)
	}
	
	return cs.SaveConfig()
}

// ResetConfig 重置为默认配置
func (cs *ConfigService) ResetConfig() error {
	cs.mutex.Lock()
	defer cs.mutex.Unlock()
	
	cs.setDefaultConfig()
	return cs.SaveConfig()
}

// GetEditorConfig 获取编辑器配置
func (cs *ConfigService) GetEditorConfig() map[string]interface{} {
	editorConfig := cs.GetConfig("editor")
	if editorConfig == nil {
		return cs.getDefaultEditorConfig()
	}
	return editorConfig.(map[string]interface{})
}

// GetRenderConfig 获取渲染配置
func (cs *ConfigService) GetRenderConfig() map[string]interface{} {
	renderConfig := cs.GetConfig("render")
	if renderConfig == nil {
		return cs.getDefaultRenderConfig()
	}
	return renderConfig.(map[string]interface{})
}

// GetExportConfig 获取导出配置
func (cs *ConfigService) GetExportConfig() map[string]interface{} {
	exportConfig := cs.GetConfig("export")
	if exportConfig == nil {
		return cs.getDefaultExportConfig()
	}
	return exportConfig.(map[string]interface{})
}

// createDefaultConfig 创建默认配置文件
func (cs *ConfigService) createDefaultConfig() error {
	cs.setDefaultConfig()
	return cs.saveConfigInternal()
}

// setDefaultConfig 设置默认配置
func (cs *ConfigService) setDefaultConfig() {
	cs.config = map[string]interface{}{
		"app": map[string]interface{}{
			"name":    "MarkEdit",
			"version": "1.0.0",
			"port":    8080,
			"debug":   false,
		},
		"editor":   cs.getDefaultEditorConfig(),
		"render":   cs.getDefaultRenderConfig(),
		"export":   cs.getDefaultExportConfig(),
		"security": cs.getDefaultSecurityConfig(),
		"storage":  cs.getDefaultStorageConfig(),
	}
}

// getDefaultEditorConfig 获取默认编辑器配置
func (cs *ConfigService) getDefaultEditorConfig() map[string]interface{} {
	return map[string]interface{}{
		"theme":           "default",
		"font_size":       14,
		"font_family":     "Monaco, Consolas, 'Courier New', monospace",
		"line_numbers":    true,
		"word_wrap":       true,
		"auto_save":       true,
		"auto_save_delay": 2000,
		"tab_size":        2,
		"indent_type":     "spaces",
		"vim_mode":        false,
		"live_preview":    true,
		"spell_check":     false,
		"syntax_highlight": true,
		"bracket_matching": true,
		"auto_complete":   true,
		"minimap":         false,
	}
}

// getDefaultRenderConfig 获取默认渲染配置
func (cs *ConfigService) getDefaultRenderConfig() map[string]interface{} {
	return map[string]interface{}{
		"mermaid": map[string]interface{}{
			"theme":      "default",
			"background": "white",
			"width":      800,
			"height":     600,
		},
		"plantuml": map[string]interface{}{
			"server": "http://www.plantuml.com/plantuml",
			"format": "png",
			"theme":  "default",
		},
		"katex": map[string]interface{}{
			"display_mode":    false,
			"throw_on_error":  false,
			"error_color":     "#cc0000",
			"macros":          map[string]interface{}{},
			"strict":          "warn",
			"trust":           false,
			"fleqn":           false,
			"leqno":           false,
		},
		"code_highlight": map[string]interface{}{
			"theme":       "github",
			"line_numbers": true,
			"copy_button": true,
		},
	}
}

// getDefaultExportConfig 获取默认导出配置
func (cs *ConfigService) getDefaultExportConfig() map[string]interface{} {
	return map[string]interface{}{
		"pdf": map[string]interface{}{
			"format":      "A4",
			"orientation": "portrait",
			"margin": map[string]interface{}{
				"top":    "1in",
				"bottom": "1in",
				"left":   "1in",
				"right":  "1in",
			},
			"header": map[string]interface{}{
				"enabled": false,
				"content": "",
			},
			"footer": map[string]interface{}{
				"enabled": true,
				"content": "页码: {page}/{total}",
			},
			"quality": 300,
		},
		"word": map[string]interface{}{
			"format": "docx",
			"style":  "default",
			"margin": map[string]interface{}{
				"top":    "1in",
				"bottom": "1in",
				"left":   "1in",
				"right":  "1in",
			},
		},
		"html": map[string]interface{}{
			"standalone":    true,
			"include_css":   true,
			"include_js":    true,
			"template":      "default",
		},
	}
}

// getDefaultSecurityConfig 获取默认安全配置
func (cs *ConfigService) getDefaultSecurityConfig() map[string]interface{} {
	return map[string]interface{}{
		"cors": map[string]interface{}{
			"enabled":         true,
			"allowed_origins": []string{"*"},
			"allowed_methods": []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
			"allowed_headers": []string{"*"},
		},
		"rate_limit": map[string]interface{}{
			"enabled":     true,
			"requests":    100,
			"window":      "1m",
		},
		"file_upload": map[string]interface{}{
			"max_size":        "10MB",
			"allowed_types":   []string{".md", ".txt", ".jpg", ".png", ".gif", ".svg"},
		},
	}
}

// getDefaultStorageConfig 获取默认存储配置
func (cs *ConfigService) getDefaultStorageConfig() map[string]interface{} {
	return map[string]interface{}{
		"documents_path": "./documents",
		"temp_path":      "./temp",
		"cache_path":     "./cache",
		"backup": map[string]interface{}{
			"enabled":   true,
			"interval":  "24h",
			"retention": "30d",
		},
	}
}

// getNestedValue 获取嵌套配置值
func (cs *ConfigService) getNestedValue(config map[string]interface{}, key string) interface{} {
	v := viper.New()
	for k, val := range config {
		v.Set(k, val)
	}
	return v.Get(key)
}

// setNestedValue 设置嵌套配置值
func (cs *ConfigService) setNestedValue(config map[string]interface{}, key string, value interface{}) {
	v := viper.New()
	for k, val := range config {
		v.Set(k, val)
	}
	v.Set(key, value)
	
	// 更新配置映射
	for k := range config {
		delete(config, k)
	}
	for k, val := range v.AllSettings() {
		config[k] = val
	}
}

// deepCopy 深拷贝配置
func (cs *ConfigService) deepCopy(src, dst map[string]interface{}) {
	for k, v := range src {
		switch val := v.(type) {
		case map[string]interface{}:
			dst[k] = make(map[string]interface{})
			cs.deepCopy(val, dst[k].(map[string]interface{}))
		default:
			dst[k] = v
		}
	}
}

// 为了兼容handler中的调用，添加方法别名
func (cs *ConfigService) Get(key string) interface{} {
	return cs.GetConfig(key)
}

func (cs *ConfigService) GetAll() map[string]interface{} {
	return cs.GetAllConfig()
}

func (cs *ConfigService) Update(updates map[string]interface{}) error {
	return cs.UpdateConfig(updates)
}

func (cs *ConfigService) Set(key string, value interface{}) error {
	return cs.SetConfig(key, value)
}

func (cs *ConfigService) Reset() error {
	return cs.ResetConfig()
}

func (cs *ConfigService) Save() error {
	return cs.SaveConfig()
}

func (cs *ConfigService) Load() error {
	return cs.LoadConfig()
}

// ValidateConfig 验证配置
func (cs *ConfigService) ValidateConfig() []string {
	var errors []string
	
	// 验证应用配置
	if port := cs.GetConfig("app.port"); port != nil {
		if p, ok := port.(float64); !ok || p < 1 || p > 65535 {
			errors = append(errors, "app.port must be a valid port number (1-65535)")
		}
	}
	
	// 验证编辑器配置
	if fontSize := cs.GetConfig("editor.font_size"); fontSize != nil {
		if fs, ok := fontSize.(float64); !ok || fs < 8 || fs > 72 {
			errors = append(errors, "editor.font_size must be between 8 and 72")
		}
	}
	
	// 验证渲染配置
	if plantumlServer := cs.GetConfig("render.plantuml.server"); plantumlServer != nil {
		if server, ok := plantumlServer.(string); !ok || server == "" {
			errors = append(errors, "render.plantuml.server must be a valid URL")
		}
	}
	
	return errors
}